package com.spice.service.entity.job;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.spice.service.entity.pojo.*;
import com.spice.service.util.MultipartFileUtil;
import com.spice.service.util.ServiceUtil;
import lombok.Getter;

import java.io.File;
import java.util.*;

/**
 * 删除多余文件任务
 * 清理的对象都必须存在了一段时间
 * 清理对象：
 * 1.不在数据库的备份
 * 2.不再使用的图片、文档
 * 3.导入导出临时文件
 */

public class CleanupFileJob extends Job {

    /**
     * service工具，用于检索数据库
     */
    private ServiceUtil serviceUtil;
    /**
     * 当前所有文件
     */
    @Getter
    private File[] files = MultipartFileUtil.getFiles();
    /**
     * 脱离保护期的文件数组
     */
    @Getter
    private List<File> unprotectedFiles = new ArrayList<>();
    /**
     * 正在使用的文件名数组
     */
    @Getter
    private Set<String> usingFileNames = new HashSet<>();
    /**
     * 已经被删除的文件名数组
     */
    @Getter
    private List<String> deletedFileNames = new ArrayList<>();
    /**
     * 保护时长，即距今的时间差，超过该时间则脱离保护
     */
    private static final long PROTECT_TIME_LAG = (long) 1000 * 60 * 60 * 7;

    /**
     * @param serviceUtil
     */

    public CleanupFileJob(ServiceUtil serviceUtil) {
        this.serviceUtil = serviceUtil;
    }

    /**
     * 初始化unprotectedFileNames和usingFileNames
     * 判断文件是否脱离保护期
     * 扫描数据库，获取正在使用的图片和文档
     *
     * @throws Exception
     */
    @Override
    protected void initializeMethod() throws Exception {
        long now = new Date().getTime();
        for (File file : files) {
            long lag = now - MultipartFileUtil.getCreateTime(file.getName()).getTime();
            if (lag > PROTECT_TIME_LAG) {
                unprotectedFiles.add(file);
            }
        }
        //图片存储格式为url
        // 扫描用户表
        List<User> userList = serviceUtil.userService
                .list(new LambdaQueryWrapper<User>().select(User::getAvatar));
        for (User user : userList) {
            usingFileNames.add(splitURL(user.getAvatar()));
        }
        finishPercent(10);
        // 扫描外形表
        List<ShapeDesc> shapeDescList = serviceUtil.shapeDescService
                .list(new LambdaQueryWrapper<ShapeDesc>().select(ShapeDesc::getPicture));
        for (ShapeDesc shapeDesc : shapeDescList) {
            usingFileNames.add(splitURL(shapeDesc.getPicture()));
        }
        finishPercent(10);
        // 扫描辣椒表
        List<ChiliStudy> chiliStudyList = serviceUtil.chiliStudyService
                .list(new LambdaQueryWrapper<ChiliStudy>().select(ChiliStudy::getExteriorPicture));
        for (ChiliStudy chiliStudy : chiliStudyList) {
            usingFileNames.add(splitURL(chiliStudy.getExteriorPicture()));
        }
        finishPercent(10);
        // 扫描花椒表
        List<FlowerChiliStudy> flowerChiliStudyList = serviceUtil.flowerChiliStudyService
                .list(new LambdaQueryWrapper<FlowerChiliStudy>().select(FlowerChiliStudy::getExteriorPicture));
        for (FlowerChiliStudy flowerChiliStudy : flowerChiliStudyList) {
            usingFileNames.add(splitURL(flowerChiliStudy.getExteriorPicture()));
        }
        finishPercent(10);
        //文档存储格式为文件名
        List<DocumentInfo> documentInfoList = serviceUtil.documentInfoService
                .list(new LambdaQueryWrapper<DocumentInfo>().select(DocumentInfo::getLocalFileName));
        for (DocumentInfo documentInfo : documentInfoList) {
            usingFileNames.add(documentInfo.getLocalFileName());
        }
        finishPercent(10);
    }


    @Override
    protected Boolean runMethod() throws Exception {
        // 删除多余文件
        int realDeleteNumber = 0;
        for (File file : unprotectedFiles) {
            if (!usingFileNames.contains(file.getName())) {
                if (FileUtil.del(file)) {
                    deletedFileNames.add(file.getName());
                    realDeleteNumber++;
                } else {
                    return false;
                }
            }
        }
        finishPercent(50);
        return true;
    }


    private String splitURL(String url) {
        if (url != null && url.startsWith("http") && url.contains("/")) {
            return url.substring(url.lastIndexOf("/") + 1);
        } else {
            return "";
        }
    }

}
